<!DOCTYPE html>
<html>
<!-- 可以在浏览器中打开，也可用于自动化测试 -->

<head>
  <meta charset="utf-8" />
  <title>data-combine</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    target {
      display: block;
    }

    .main {
      margin: 0 auto 50px;
      width: 665px;
    }

    h3,
    li {
      margin-bottom: 30px;
    }

    .tip {
      margin: 10px 0;
      display: block;
      color: red;
    }

    .combineAll {
      width: 300px;
      height: 50px;
    }
  </style>
</head>

<body>
  <!-- <target>标签里的内容，为自动化测试要用到的内容，需要与将生成的数据一致 -->
  <div class="main">
    <h3>dataCombine取DOM数据时，与模板引擎(如artTemplate)的“感觉”相反</h3>
    <ol id="exampleList">
      <li>
        <h4>表单元素生成json</h4>
        <div class="to-combine">
          <div class="tip">* e-combine为默认关键属性</div>
          <input e-combine="name" type="text" value="1" />
          <input e-combine="age" type="radio" value="2" />
          <input e-combine="grade" type="checkbox" value="3" />
          <select e-combine="birthDate">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09">2018-06-09</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '1', age: '2', grade: '3', birthDate: '2018-06-09' }
        </target>
      </li>
      <li>
        <h4>非表单元素生成json</h4>
        <div class="to-combine">
          <div class="tip">* 表单元素默认取value值，非表单元素默认取e-value值</div>
          <span e-combine="name" e-value="1">1</span>
          <em e-combine="age" e-value="2">2</em>
          <i e-combine="grade" e-value="3">3</i>
          <strong e-combine="birthDate" e-value="2018-06-09">2018-06-09</strong>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '1', age: '2', grade: '3', birthDate: '2018-06-09' }
        </target>
      </li>
      <li>
        <h4>生成数组</h4>
        <div class="to-combine" e-combine="{[]}">
          <div class="tip">
            * 其中[]为默认关键字<br /> 
            * 注意父元素的e-combine="{[]}"哟
          </div>
          <input e-combine="[]" type="text" value="1" />
          <input e-combine="[]" type="radio" value="2" />
          <input e-combine="[]" type="checkbox" value="3" />
          <select e-combine="[]">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09">2018-06-09</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          ['1', '2', '3', '2018-06-09']
        </target>
      </li>
      <li>
        <h4>取非默认DOM属性值</h4>
        <div class="to-combine">
          <div class="tip">* 默认关键字为";"，且定义的属性名与DOM属性对应即可</div>
          <input e-combine="name;real-name" type="text" value="1" real-name="11" />
          <input e-combine="age;real-age" type="radio" value="2" real-age="22" />
          <input e-combine="grade;other-grade" type="checkbox" value="3" other-grade="33" />
          <select e-combine="birthDate;real-birth-date" real-birth-date="2018-06-19">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09">2018-06-09</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '11', age: '22', grade: '33', birthDate: '2018-06-19' }
        </target>
      </li>
      <li>
        <h4>取任意属性值</h4>
        <div class="to-combine">
          <div class="tip">
            * 需要使用dataCombine.pickCommand自定义“取值器” (参见combineConfig.js) <br /> 
            * 其实，省略不写时，使用默认“取值器”指令方法pick() =》 表单元素取dom.value，非表单元素dom.getAttribute('e-value') <br /> 
            * 没错，上面的 e-combine="name;real-name" 等价于 e-combine="name;pick(real-name)"
          </div>
          <input e-combine="name;addSome(2)" type="text" value="1" />
          <input e-combine="age;addSome(2)" type="radio" value="2" />
          <input e-combine="grade;addSome(63)" type="checkbox" value="3" />
          <select e-combine="birthDate;addSome()">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09">2018-06-09</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '12', age: '22', grade: '363', birthDate: '2018-06-09' }
        </target>
      </li>
      <li>
        <h4>取值后类型转换</h4>
        <div class="to-combine">
          <div class="tip">
            * 除string外，需要使用dataCombine.convertCommand自定义“转换器”(参见combineConfig.js)<br /> 
            * 其中";"为默认关键字，使用默认 pickCommand 和 convertCommand 时，都可以省略哟
          </div>
          <input e-combine="name;;number" type="text" value="1" />
          <input e-combine="age;;number" type="radio" value="2" />
          <input e-combine="grade;;string" type="checkbox" value="3" />
          <input e-combine="hobby;;split" type="checkbox" value="111,222,333" />
          <select e-combine="birthDate;;date">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09 00:00:00">2018-06-09 00:00:00</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: 1, age: 2, grade: '3', hobby: ['111', '222', '333'], birthDate: '2018-06-09' }
        </target>
      </li>
      <li>
        <h4>取值依赖（条件判断）</h4>
        <div class="to-combine">
          <div class="tip">
            * 其中"@"为默认关键字<br /> 
            * 还记得么，使用默认 pickCommand 和 convertCommand 时，都可以省略哟<br />
          </div>
          <input e-combine="name@to-combine=true" type="text" to-combine="true" value="1" />
          <input e-combine="age@to-combine=true;;number" type="radio" to-combine="false" value="2" />
          <input e-combine="age@to-combine=true;;number" type="radio" to-combine="true" value="22" />
          <input e-combine="grade@rely=something;double();length(6)" rely="something" type="checkbox" value="1234" />
          <select e-combine="birthDate@no-combine=;;date" no-combine="">
            <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
            <option selected value="2018-06-09 00:00:00">2018-06-09 00:00:00</option>
          </select>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '1', age: 22, grade: '123412', birthDate: '2018-06-09' }
        </target>
      </li>
      <li>
        <h4>自定义取值依赖（自定义条件判断）</h4>
        <div class="to-combine">
          <div class="tip">
            * 需要使用dataCombine.relyCommand自定义“依赖器”(参见combineConfig.js)<br /> 
            * 注意哟，多参数使用空白字符分隔，而<strong>不是</strong>使用","分隔哟<br /> 
            * 虽然介绍“依赖器”比较靠后，但实际执行时，执行顺序是“依赖器”->“取值器”->“转换器”<br /> 
            * 其实，省略不写时，使用默认“依赖器”指令方法rely() <br /> 
            * 没错，e-combine="name@to-combine=true" 等价于 e-combine="name@rely(to-combine true)"
          </div>
          <input e-combine="name@isNumber()" type="text" value="1" />
          <input e-combine="age@between(10 30);;number" type="radio" value="2" />
          <input e-combine="age@between(10 30)" type="radio" to-combine="true" value="22" />
          <input e-combine="grade@between(200 300);double();length(6)" type="checkbox" value="1234" />
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { name: '1', age: '22' }
        </target>
      </li>
      <li>
        <h4>数据嵌套组合-json嵌套json</h4>
        <div class="to-combine">
          <div class="tip">
            * 要变为子集的DOM节点上，加上e-combine属性<br /> 
            * 其中"{}"为默认关键字<br /> 
            * 支持无限级嵌套哟
          </div>
          <p e-combine="{sonJsonOne}">
            <input e-combine="name" type="text" value="1" />
            <input e-combine="age" type="radio" value="2" />
          </p>
          <p e-combine="{sonJsonTwo}">
            <input e-combine="grade" type="checkbox" value="3" />
            <select e-combine="birthDate">
              <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
              <option selected value="2018-06-09">2018-06-09</option>
            </select>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { sonJsonOne: {name: '1', age: '2'}, sonJsonTwo: {grade: '3' ,birthDate: '2018-06-09'} }
        </target>
      </li>
      <li>
        <h4>数据嵌套组合-json嵌套array</h4>
        <div class="to-combine">
          <div class="tip">
            * 注意"[]"与pickCommand 和 convertCommand的位置
          </div>
          <p e-combine="{[arrayOne]}">
            <input e-combine="[];;number" type="text" value="1" />
            <input e-combine="[]" type="radio" value="2" />
          </p>
          <p e-combine="{[arrayTwo]}">
            <input e-combine="[]" type="checkbox" value="3" />
            <select e-combine="[]">
              <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
              <option selected value="2018-06-09">2018-06-09</option>
            </select>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { arrayOne: [1, '2'], arrayTwo: ['3', '2018-06-09'] }
        </target>
      </li>
      <li>
        <h4>数据嵌套组合-array嵌套array</h4>
        <div class="to-combine">
          <div class="tip">
            * 注意"{}"里面的array，没错，默认为json，可以省略
          </div>
          <p e-combine="{[arrayOne]}">
            <input e-combine="[];;number" type="text" value="1" />
            <input e-combine="[]" type="radio" value="2" />
          </p>
          <p e-combine="{[arrayOne]}">
            <input e-combine="[];;number" type="text" value="11" />
            <input e-combine="[]" type="radio" value="22" />
          </p>
          <p e-combine="{[arrayTwo]}">
            <input e-combine="[]" type="checkbox" value="3" />
            <select e-combine="[]">
              <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
              <option selected value="2018-06-09">2018-06-09</option>
            </select>
          </p>
          <p e-combine="{[arrayTwo]}">
            <input e-combine="[]" type="checkbox" value="33" />
            <select e-combine="[]">
              <option selected value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
              <option value="2018-06-09">2018-06-09</option>
            </select>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { arrayOne: [1, '2', 11, '22'], arrayTwo: ['3', '2018-06-09', '33', '2018-01-01 00:00:00'] }
        </target>
      </li>
      <li>
        <h4>数据嵌套组合-array嵌套json</h4>
        <div class="to-combine">
          <div class="tip">
            * 基本用法，说完了。<br /> 
            * 如果你发现在浏览器中，data-combine对dom结构有依赖，那恭喜了，你很有洞察力
          </div>
          <p e-combine="{[arrayOne]}">
            <input e-combine="[];;number" type="text" value="1" />
            <span e-combine="{}">
              <input e-combine="age;;number" type="text" value="11" />
              <input e-combine="name" type="radio" value="22" />
            </span>
          </p>
          <p e-combine="{[arrayTwo]}">
            <input e-combine="[]" type="checkbox" value="3" />
            <span e-combine="{}">
              <input e-combine="grade" type="checkbox" value="33" />
              <select e-combine="birthDate">
                <option value="2018-01-01 00:00:00">2018-01-01 00:00:00</option>
                <option selected value="2018-06-09">2018-06-09</option>
              </select>
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { arrayOne: [1, {age: 11, name: '22'}], arrayTwo: ['3', {grade: '33', birthDate: '2018-06-09'}] }
        </target>
      </li>
      <li>
        <h4>后面将介绍各种特别用法喽——选取性取值</h4>
        <div class="to-combine">
          <div class="tip">
            * 其中getAttr也是自定义的pickCommand哟<br />
          </div>
          <p>
            <input e-combine="age;getAttr(value)|getAttr(other);number" type="text" other="2" value="1" />
            <input e-combine="name;getAttr(value)|getAttr(other)" type="radio" other="2" value="" />
            <span e-combine="{[arr]}">
              <span e-combine="[];getAttr(attr-name)|getAttr(attr-other)" attr-name="L" attr-other="2"></span>
              <span e-combine="[];getAttr(attr-name)|getAttr(attrOther)" attr-name="" attrOther="2"></span>
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { age: 1, name: '2', arr: ['L', '2'] }
        </target>
      </li>
      <li>
        <h4>多条件取值依赖</h4>
        <div class="to-combine">
          <div class="tip">
            * 其中getAttr也是自定义的pickCommand哟<br />
          </div>
          <p>
            <input e-combine="age@other=2&value=1;;number" type="text" other="2" value="1" />
            <input e-combine="name@other!=2" type="radio" other="2" value="55" />
            <span e-combine="{[arr]}">
              <span e-combine="[]@attr-name=A|attr-name=L;" attr-name="L" e-value="2"></span>
              <span e-combine="[]@attr-name=&attrOther=2" attr-name="" attrOther="2" e-value="33"></span>
              <input type="text" e-combine="[]@isNumber()&between(90 110);;number" value="100" />
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { age: 1, arr: ['2', '33', 100] }
        </target>
      </li>
      <li>
        <h4>同时取多个字段值</h4>
        <div class="to-combine">
          <div class="tip">
            * 没看错，取多个字段时，默认关键字为","<br /> 
            * 多说一句，关键字左右，是可以加空格的。
          </div>
          <p>
            <input e-combine="id, text; value,text;number,string" type="radio" text="combine" value="1" />
            <!-- 只有末尾的","可以省略哟 -->
            <span e-combine="{[idArr, textArr]}">
              <input e-combine="[], []; , text ; number" type="radio" text="dataCombine" value="10" />
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { id: 1, text: 'combine', idArr: [10, 'dataCombine'], textArr: [10, 'dataCombine'] }
        </target>
      </li>
      <li>
        <h4>多“取值器”协作</h4>
        <div class="to-combine">
          <div class="tip">
            * 没看错，多个“取值器”之间，使用默认关键字为"|"
          </div>
          <p>
            <input e-combine="id;empty2undefined()|getAttr(e-id);number" type="radio" text="combine" e-id="11" value="" />
            <input e-combine="name;empty2undefined()|getAttr(e-name);" type="radio" text="combine" e-name="11" value="123" />
            <input e-combine="grade;|getAttr(e-grade);" type="radio" text="combine" e-grade="11" value="100" />
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { id: 11, name: '123', grade: '100' }
        </target>
      </li>
      <li>
        <h4>json多层嵌套json “combine关系”验证</h4>
        <div class="to-combine">
          <div class="tip">
            * “combine关系”默认使用私有字段__combine__体现
          </div>
          <p e-combine="{json1}">
            <input e-combine="age;;number" type="text" value="1" />
            <span e-combine="{json2}">
              <input e-combine="age;;number" type="text" value="2" />
              <span e-combine="{json3}">
                <input e-combine="age;;number" type="text" value="3" />
              </span>
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { json1: { age: 1, json2: { age: 2, json3: { age: 3 } } } }
        </target>
      </li>
      <li>
        <h4>array多层嵌套json “combine关系”验证</h4>
        <div class="to-combine">
          <div class="tip">
            * “combine关系”默认使用私有字段__combine__体现
          </div>
          <p e-combine="{[arrayOne]}">
            <span e-combine="{}">
              <input e-combine="age;;number" type="text" value="1" />
              <input e-combine="name" type="radio" value="2" />
              <span e-combine="{[arrayTwo]}">
                <span e-combine="{}">
                  <input e-combine="age;;number" type="text" value="1" />
                  <input e-combine="name" type="radio" value="2" />
                </span>
              </span>
            </span>
          </p>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          { arrayOne: [{ age: 1, name: '2', arrayTwo: [{ age: 1, name: '2' }] }] }
        </target>
      </li>
      <li>
        <h4>层级器</h4>
        <div class="to-combine" e-combine="{[]}">
          <div class="tip">
            * 其中“->”是默认关键字。
          </div>
          <input e-combine="[];;number" type="text" value="0" />
          <span e-combine="{[] ; join(-)}">
            <input e-combine="[];;number" type="text" value="10" />
            <input e-combine="[];;number" type="text" value="20" />
          </span>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          [ 0, '10-20' ]
        </target>
      </li>
      <li>
        <h4>多层级器</h4>
        <div class="to-combine" e-combine="{[]}">
          <div class="tip">
            * 很明显，“层级器”执行顺序是从左向右。
          </div>
          <input e-combine="[];;number" type="text" value="0" />
          <span e-combine="{[] ; reverse(30) -> join(-)}">
            <input e-combine="[];;number" type="text" value="10" />
            <input e-combine="[];;number" type="text" value="20" />
          </span>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          [ 0, '30-20-10' ]
        </target>
      </li>
      <li>
        <h4>测试getParent</h4>
        <div class="to-combine" e-combine="{}">
          <div class="tip">
            * 测试getParent
          </div>
          <input e-combine="value@testGetParent();testGetParent();testGetParent" type="text" value="1" />
          <span e-combine="{son}">
            <input e-combine="value@testGetParent();testGetParent();testGetParent" type="text" value="11" />
            <span e-combine="{son}">
              <input e-combine="value@testGetParent();testGetParent();testGetParent" type="text" value="111" />
            </span>
          </span>
          <span e-combine="{[arr]}">
            <input e-combine="[]@testGetParent();testGetParent();testGetParent" type="text" value="11" />
            <span e-combine="{[]}">
              <input e-combine="[]@testGetParent();testGetParent();testGetParent" type="text" value="111" />
              <span e-combine="{[]}">
                <input e-combine="[]@testGetParent();testGetParent();testGetParent" type="text" value="1111" />
              </span>
            </span>
          </span>
        </div>
        <button>提取</button>
        <!-- 将生成的数据 -->
        <target>
          {
            value: "1",
            son: {
              value: "11",
              son: {
                value: "111"
              }
            },
            arr: [
              "11",
              [
                "111",
                [
                  "1111"
                ]
              ]
            ]
          }
        </target>
      </li>
      <li>
        <h4>myTest</h4>
        <div class="tip">
          * 目前在测试中哟。 * 自动化测试中已经去掉这一项的测试了哟
        </div>
        <div id="target">
            <input e-combine="name" type="text" value="Lone" />
            <input e-combine="sex@checked;cn-pinyin" checked type="radio" value="0" cn-pinyin="nan"/> 男
            <input e-combine="sex@checked;cn-pinyin" type="radio" value="1" cn-pinyin="nv" /> 女
            <p e-combine="{[hobbies]}">
              <input e-combine="[]@checked" checked type="checkbox" value="ping-pong" /> ping-pong
              <input e-combine="[]@checked;value" type="checkbox" value="basketball" /> basketball
              <input e-combine="[]@checked" checked type="checkbox" value="running" /> running
            </p>
            <select e-combine="{[friends]}" multiple>
              <option e-combine="[]@selected" value="Mr. Feng" selected>Mr. Feng</option>
              <option e-combine="[]@selected" value="Mr. Li">Mr. Li</option>
              <option e-combine="[]@selected" value="Mr. Liang" selected>Mr. Liang</option>
              <option e-combine="[]@selected" value="Ms. Zheng" selected>Ms. Zheng</option>
            </select>
          </div>
        <button>提取</button>
        <target>
          {
            "name": "Lone",
            "sex": "nan",
            "hobbies": [
              "ping-pong",
              "running"
            ],
            "friends": [
              "Mr. Feng",
              "Mr. Liang",
              "Ms. Zheng"
            ]
          }
        </target>
      </li>
    </ol>
    <input id="combineAllBtn" class="combineAll" type="button" value="提取所有" />
  </div>
  <script src="../src/data-combine.js"></script>
  <script src="./combineConfig.js"></script>
  <script>
    setConfig(dataCombine);
    document.onclick = function (e) {
      toCombine(e.target);
    };

    document.querySelector('#combineAllBtn').onclick = function () {
      var allBtn = document.querySelectorAll('button');
      for (var i = 0; i < allBtn.length - 1; i++) {
        console.log(i + 1);
        toCombine(allBtn[i]);
      }
    }

    function toCombine(target) {
      if (target.tagName.toLowerCase() == 'button') {
        var obj = dataCombine({
          target: target.parentNode.querySelectorAll('.to-combine')[0] || document.querySelector('#target'),  
          // relyCommand: {
          //   hasClass: function(className){
          //     return this.target.classList.contains(className);
          //   }
          // },
          // pickCommand: {
          //   pickInnerHTML: function () {
          //     return this.target.innerHTML;
          //   }
          // },
          // convertCommand: {
          //   dateFormat: function (val) {
          //     return val.replace(/-/g, '');
          //   }
          // },
          // levelCommand: {
          //   reverse: function (arr) {
          //     return arr.reverse();
          //   },
          // }
        });
        var str = JSON.stringify(obj, null, 2);
        var tarStr = JSON.stringify(new Function('return ' + target.nextElementSibling.innerText.trim())(), null, 2);
        var isRight = str === tarStr;
        if (isRight) {
          console.log(obj);
        } else {
          console.error('error');
          console.log(str);
          console.log(tarStr);
        }
      }
    }
  </script>
</body>

</html>